package models.baseinfo

import javax.inject.Inject
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
import slick.jdbc.JdbcProfile

import java.sql.Timestamp
import scala.concurrent.{ExecutionContext, Future}

class GYItemCodeRepository @Inject()(protected val dbConfigProvider: DatabaseConfigProvider)(implicit executionContext: ExecutionContext)
  extends HasDatabaseConfigProvider[JdbcProfile] {

  import dbConfig._
  import profile.api._

  private class GYItemCodeTable(tag: Tag) extends Table[GYItemCode](tag, "IMED_GYITEMCODE") {
    def id = column[Long]("ID", O.PrimaryKey)

    def gyItemId = column[Long]("gyItemId".toUpperCase)

    def gyCode = column[String]("gyCode".toUpperCase)

    def gyBarcode = column[String]("gyBarcode".toUpperCase)

    def gyName = column[String]("gyName".toUpperCase)

    def status = column[Boolean]("Status".toUpperCase)

    def kdFMaterialId = column[Int]("FMaterialId".toUpperCase)

    def kdNumber = column[String]("FNumber".toUpperCase)

    def kdFName = column[String]("FName".toUpperCase)

    def kdBarcode = column[String]("FBARCODE".toUpperCase)

    def kdFBaseUnit = column[String]("FBASEUNIT")

    def kdErpClsId = column[String]("ErpClsId".toUpperCase)

    def gyWeight = column[Double]("gyWeight".toUpperCase)

    def gyVolume = column[Double]("gyVolume".toUpperCase)

    def kdWeight = column[Double]("kdWeight".toUpperCase)

    def kdWeightUnit = column[String]("kdWeightUnit".toUpperCase)

    def kdLength = column[Double]("kdLength".toUpperCase)

    def kdWidth = column[Double]("kdWidth".toUpperCase)

    def kdHeight = column[Double]("kdHeight".toUpperCase)

    def kdVolume = column[Double]("kdVolume".toUpperCase)

    def kdVolumeUnit = column[String]("kdVolumeUnit".toUpperCase)

    def upDate = column[Timestamp]("UP_DATE")

    def * = (id, gyItemId, gyCode, gyBarcode, gyName, status,
      kdFMaterialId, kdNumber, kdFName, kdBarcode, kdFBaseUnit, kdErpClsId, gyWeight, gyVolume,
      kdWeight, kdWeightUnit, kdLength, kdWidth, kdHeight, kdVolume, kdVolumeUnit, upDate)
      .<>((GYItemCode.apply _).tupled, GYItemCode.unapply)

  }

  private val itemCodeTable = TableQuery[GYItemCodeTable]

  def list = db.run(itemCodeTable.map(f => f).result)

  def insert(itemCode: GYItemCode) =
    db.run(itemCodeTable.filter(_.kdNumber === itemCode.kdNumber).result)
      .flatMap { r =>
        if (r.nonEmpty) {
          db.run {
            itemCodeTable.filter(_.kdNumber === itemCode.kdNumber)
              .map { f =>
                (f.kdFMaterialId, f.kdFName, f.kdBarcode, f.kdFBaseUnit, f.upDate, f.kdErpClsId,
                  f.kdWeight, f.kdWeightUnit, f.kdLength, f.kdWidth, f.kdHeight, f.kdVolume, f.kdVolumeUnit)
              }
              .update((itemCode.kdMaterialId, itemCode.kdFName, itemCode.kdBarcode, itemCode.kdBaseUnit, itemCode.upDate, itemCode.kdErpClsId,
                itemCode.kdWeight, itemCode.kdWeightUnit, itemCode.kdLength, itemCode.kdWidth, itemCode.kdHeight, itemCode.kdVolume, itemCode.kdVolumeUnit))
          }
        }
        else {
          //          db.run(itemCodeTable returning itemCodeTable.map(_.id) += itemCode)
          db.run(itemCodeTable += itemCode)
        }
      }

  def update(gyItemId: Long,
             gyCode: String,
             gyBarcode: String,
             gyName: String,
             gyWeight: Double = 0,
             gyVolume: Double = 0,
             status: Boolean = false
            ) = db.run {
    itemCodeTable.filter(_.kdNumber === gyCode)
      .map(f => (f.gyItemId, f.gyCode, f.gyName, f.gyBarcode, f.status, f.gyWeight, f.gyVolume))
      .update((gyItemId, gyCode, gyName, gyBarcode, status, gyWeight, gyVolume))
  }

  def updateKd(itemCode: GYItemCode) = db.run {
    itemCodeTable.filter(_.kdNumber === itemCode.kdNumber)
      .map { f => (f.kdFMaterialId, f.kdFName, f.kdBarcode, f.kdFBaseUnit, f.kdErpClsId) }
      .update((itemCode.kdMaterialId, itemCode.kdFName, itemCode.kdBarcode, itemCode.kdBaseUnit, itemCode.kdErpClsId))
  }

}
